package com.baomidou.springboot.util;

import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

/**
 * @version 1.0
 * @create 2021/3/9 14:07
 */
public class AESUtil {
    private static final String CHARSET = "utf-8";

    /**
     * 加密
     *
     * @return
     */
    public static String encrypt(String text, String aesKey) throws NoSuchAlgorithmException, UnsupportedEncodingException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {

            // 对密钥进行MD5处理
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            byte[] aesKeyBytes = md5.digest(aesKey.getBytes(CHARSET));
            String encodeToString = Base64.getEncoder().encodeToString(aesKeyBytes);
            // AES
            Cipher cipher = Cipher.getInstance("AES");
            SecretKeySpec keySpec = new SecretKeySpec(aesKeyBytes, "AES");
            cipher.init(Cipher.ENCRYPT_MODE, keySpec);
            // 加密
            byte[] encrypted = cipher.doFinal(text.getBytes(CHARSET));
            // 将密文转换成hexString
            String HexString = BytesHexStringUtil.bytesToHexString(encrypted);
            return HexString;

    }

    /**
     * 短信手机号加密
     *
     */
    public static String msgEncrypt(String text, String aesKey) {
        try {
            aesKey = MD5Util.encrypt16(aesKey);
            IvParameterSpec zeroIv = new IvParameterSpec(aesKey.getBytes(CHARSET));
            SecretKeySpec sks = new SecretKeySpec(aesKey.getBytes(CHARSET), "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, sks, zeroIv);
            byte[] encryptedData = cipher.doFinal(text.getBytes(CHARSET));
            return Base64.getEncoder().encodeToString(encryptedData);
        } catch (Exception e) {
            return "";
        }
    }

    /**
     * 解密
     *
     * @return
     */
    public static String decrypt(String text, String aesKey) throws BadPaddingException, NoSuchAlgorithmException, UnsupportedEncodingException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException {
        // 对密钥进行MD5处理
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        byte[] aesKeyBytes = md5.digest(aesKey.getBytes(CHARSET));
        String encodeToString = Base64.getEncoder().encodeToString(aesKeyBytes);


        // AES
        Cipher cipher = Cipher.getInstance("AES");
        SecretKeySpec keySpec = new SecretKeySpec(aesKeyBytes, "AES");
        cipher.init(Cipher.DECRYPT_MODE, keySpec);

        // 将hexString密文转换成byte数组
        byte[] hexEncrypted = BytesHexStringUtil.hexStringToBytes(text);

        // 解密
        byte[] decrypted = cipher.doFinal(hexEncrypted);
        return new String(decrypted, CHARSET);


    }


    /**
     * 随机生成秘钥
     */
    public static void getKey() {
        try {
            KeyGenerator kg = KeyGenerator.getInstance("AES");
            kg.init(128);
            //要生成多少位，只需要修改这里即可128, 192或256
            SecretKey sk = kg.generateKey();
            byte[] b = sk.getEncoded();
            String s = byteToHexString(b);
            System.out.println(s);
        }
        catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            System.out.println("没有此算法。");
        }
    }

    /**
     * byte数组转化为16进制字符串
     * @param bytes
     * @return
     */
    public static String byteToHexString(byte[] bytes) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < bytes.length; i++) {
            String strHex=Integer.toHexString(bytes[i]);
            if(strHex.length() > 3) {
                sb.append(strHex.substring(6));
            } else {
                if(strHex.length() < 2) {
                    sb.append("0" + strHex);
                } else {
                    sb.append(strHex);
                }
            }
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        getKey();
    }

}
